#ifndef SEQUENCE_TYPEFUSER_H
#define SEQUENCE_TYPEFUSER_H

#define VALID_OBJECT_TYPE 10
#define HISTORY_CCRF_FRAME 20

#include "postprocess/type_fuser/base_typefuser.h"
#include "common/fixed_array.h"
#include "postprocess/common/common_func.h"
#include <vector>
#include <deque>

typedef Eigen::Matrix<float, VALID_OBJECT_TYPE, 1> Vectorf;
typedef Eigen::Matrix<int, VALID_OBJECT_TYPE, 1> Vectori;

class SequenceTypeFuser : public BaseTypeFuser {
 public:
  /// @brief Constructor
  SequenceTypeFuser();

  /// @brief Destructor
  ~SequenceTypeFuser();

  /// @brief Init parameters
  /// @param
  /// @return True if fuse type successfully, false otherwise
  void Init(int type_count) override;

  /// @brief Fuse type for each object
  /// @param
  /// @param
  /// @return
  int FuseType() override;

  /// @brief set type count
  /// @param
  inline void SetTypeCount(int count) { type_count_ = count; };

  /// @brief get type count
  /// @param
  /// @return
  inline int GetTypeCount() const { return type_count_; };

  /// @brief add object probs
  /// @param
  /// @return
  void AddObjectProbs(TrackedObjectPtr* new_object);

  /// @brief
  /// @param
  /// @return
  void ToExp(Vectorf* prob);

  /// @brief
  /// @param
  /// @return
  void Normalize(Vectorf* prob);

  /// @brief
  /// @param
  /// @return
  void FromEigenVector(const Vectorf& src_prob, std::vector<float>* dst_prob);

 private:
  /// @brief type count
  int type_count_;
  /// @brief transiton matrix
  Eigen::MatrixXf A_;
  /// @brief origin object total class scores(10 category)
  std::deque<Vectorf> fused_oneshot_probs_;
  /// @brief fixed object total class scores(10 category)
  std::vector<Vectorf> fused_sequence_probs_;
  /// @brief alpha
  float s_alpha_;
};

#endif